package com.cardcaptorsakura.service.output;

import com.cardcaptorsakura.model.dto.*;
import com.cardcaptorsakura.model.entity.PersonaConfig;
import com.cardcaptorsakura.service.persona.PersonaService;
import com.cardcaptorsakura.service.memory.MemoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 多模态输出服务
 * 协调文本、图像、语音等多种输出模式，提供统一的输出接口
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MultiModalOutputService {

    private final TextGenerationService textGenerationService;
    private final ImageGenerationService imageGenerationService;
    private final VoiceSynthesisService voiceSynthesisService;
    private final PersonaService personaService;
    private final MemoryService memoryService;
    
    private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    /**
     * 处理多模态输出请求
     *
     * @param request 多模态输出请求
     * @return 多模态输出响应
     */
    public MultiModalOutputResponse processMultiModalOutput(MultiModalOutputRequest request) {
        try {
            log.info("Processing multi-modal output for user: {}, modes: {}", 
                    request.getUserId(), request.getOutputModes());
            
            MultiModalOutputResponse.Builder responseBuilder = MultiModalOutputResponse.builder()
                    .requestId(request.getRequestId())
                    .userId(request.getUserId())
                    .processedAt(LocalDateTime.now());
            
            List<CompletableFuture<Void>> futures = new ArrayList<>();
            
            // 并行处理各种输出模式
            for (OutputMode mode : request.getOutputModes()) {
                switch (mode) {
                    case TEXT:
                        futures.add(processTextOutput(request, responseBuilder));
                        break;
                    case IMAGE:
                        futures.add(processImageOutput(request, responseBuilder));
                        break;
                    case VOICE:
                        futures.add(processVoiceOutput(request, responseBuilder));
                        break;
                    case COMBINED:
                        futures.add(processCombinedOutput(request, responseBuilder));
                        break;
                }
            }
            
            // 等待所有任务完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            
            MultiModalOutputResponse response = responseBuilder.build();
            
            // 保存输出记录到记忆系统
            saveOutputToMemory(request, response);
            
            log.info("Completed multi-modal output processing for user: {}", request.getUserId());
            return response;
            
        } catch (Exception e) {
            log.error("Error processing multi-modal output for user: {}", request.getUserId(), e);
            throw new RuntimeException("Failed to process multi-modal output: " + e.getMessage(), e);
        }
    }

    /**
     * 处理文本输出
     */
    private CompletableFuture<Void> processTextOutput(MultiModalOutputRequest request, 
                                                     MultiModalOutputResponse.Builder responseBuilder) {
        return CompletableFuture.runAsync(() -> {
            try {
                ChatRequest chatRequest = ChatRequest.builder()
                        .userId(request.getUserId())
                        .text(request.getInputText())
                        .options(request.getOptions())
                        .build();
                
                String textResponse = textGenerationService.generateText(chatRequest);
                
                // 根据人格个性化响应
                PersonaConfig persona = personaService.getActivePersona(request.getUserId());
                String personalizedResponse = textGenerationService.personalizeResponse(textResponse, persona);
                
                synchronized (responseBuilder) {
                    responseBuilder.textResponse(personalizedResponse);
                }
                
                log.debug("Generated text response for user: {}", request.getUserId());
                
            } catch (Exception e) {
                log.error("Error generating text output for user: {}", request.getUserId(), e);
                synchronized (responseBuilder) {
                    responseBuilder.textResponse("抱歉，我现在无法生成文本回复。请稍后再试。");
                }
            }
        }, executorService);
    }

    /**
     * 处理图像输出
     */
    private CompletableFuture<Void> processImageOutput(MultiModalOutputRequest request, 
                                                      MultiModalOutputResponse.Builder responseBuilder) {
        return CompletableFuture.runAsync(() -> {
            try {
                if (!StringUtils.hasText(request.getImagePrompt())) {
                    log.warn("No image prompt provided for user: {}", request.getUserId());
                    return;
                }
                
                ImageGenerationRequest imageRequest = ImageGenerationRequest.builder()
                        .userId(request.getUserId())
                        .prompt(request.getImagePrompt())
                        .width(request.getImageWidth() != null ? request.getImageWidth() : 512)
                        .height(request.getImageHeight() != null ? request.getImageHeight() : 512)
                        .style(request.getImageStyle())
                        .build();
                
                ImageGenerationResponse imageResponse = imageGenerationService.generateImage(imageRequest);
                
                synchronized (responseBuilder) {
                    responseBuilder.imageResponse(imageResponse);
                }
                
                log.debug("Generated image response for user: {}", request.getUserId());
                
            } catch (Exception e) {
                log.error("Error generating image output for user: {}", request.getUserId(), e);
                // 图像生成失败不影响其他输出模式
            }
        }, executorService);
    }

    /**
     * 处理语音输出
     */
    private CompletableFuture<Void> processVoiceOutput(MultiModalOutputRequest request, 
                                                      MultiModalOutputResponse.Builder responseBuilder) {
        return CompletableFuture.runAsync(() -> {
            try {
                // 如果没有指定语音文本，使用文本响应
                String voiceText = StringUtils.hasText(request.getVoiceText()) ? 
                        request.getVoiceText() : request.getInputText();
                
                if (!StringUtils.hasText(voiceText)) {
                    log.warn("No voice text available for user: {}", request.getUserId());
                    return;
                }
                
                VoiceSynthesisRequest voiceRequest = VoiceSynthesisRequest.builder()
                        .userId(request.getUserId())
                        .text(voiceText)
                        .voice(request.getVoice())
                        .speed(request.getVoiceSpeed())
                        .format(request.getVoiceFormat())
                        .build();
                
                VoiceSynthesisResponse voiceResponse = voiceSynthesisService.synthesizeVoice(voiceRequest);
                
                synchronized (responseBuilder) {
                    responseBuilder.voiceResponse(voiceResponse);
                }
                
                log.debug("Generated voice response for user: {}", request.getUserId());
                
            } catch (Exception e) {
                log.error("Error generating voice output for user: {}", request.getUserId(), e);
                // 语音生成失败不影响其他输出模式
            }
        }, executorService);
    }

    /**
     * 处理组合输出（文本+图像+语音）
     */
    private CompletableFuture<Void> processCombinedOutput(MultiModalOutputRequest request, 
                                                         MultiModalOutputResponse.Builder responseBuilder) {
        return CompletableFuture.runAsync(() -> {
            try {
                // 首先生成文本响应
                ChatRequest chatRequest = ChatRequest.builder()
                        .userId(request.getUserId())
                        .text(request.getInputText())
                        .options(request.getOptions())
                        .build();
                
                String textResponse = textGenerationService.generateText(chatRequest);
                PersonaConfig persona = personaService.getActivePersona(request.getUserId());
                String personalizedResponse = textGenerationService.personalizeResponse(textResponse, persona);
                
                synchronized (responseBuilder) {
                    responseBuilder.textResponse(personalizedResponse);
                }
                
                // 基于文本响应生成图像（如果需要）
                if (shouldGenerateImage(personalizedResponse, persona)) {
                    String imagePrompt = extractImagePromptFromText(personalizedResponse, persona);
                    if (StringUtils.hasText(imagePrompt)) {
                        ImageGenerationRequest imageRequest = ImageGenerationRequest.builder()
                                .userId(request.getUserId())
                                .prompt(imagePrompt)
                                .width(512)
                                .height(512)
                                .build();
                        
                        try {
                            ImageGenerationResponse imageResponse = imageGenerationService.generateImage(imageRequest);
                            synchronized (responseBuilder) {
                                responseBuilder.imageResponse(imageResponse);
                            }
                        } catch (Exception e) {
                            log.warn("Failed to generate image for combined output: {}", e.getMessage());
                        }
                    }
                }
                
                // 生成语音（基于文本响应）
                VoiceSynthesisRequest voiceRequest = VoiceSynthesisRequest.builder()
                        .userId(request.getUserId())
                        .text(personalizedResponse)
                        .build();
                
                try {
                    VoiceSynthesisResponse voiceResponse = voiceSynthesisService.synthesizeVoice(voiceRequest);
                    synchronized (responseBuilder) {
                        responseBuilder.voiceResponse(voiceResponse);
                    }
                } catch (Exception e) {
                    log.warn("Failed to generate voice for combined output: {}", e.getMessage());
                }
                
                log.debug("Generated combined output for user: {}", request.getUserId());
                
            } catch (Exception e) {
                log.error("Error generating combined output for user: {}", request.getUserId(), e);
                synchronized (responseBuilder) {
                    responseBuilder.textResponse("抱歉，我现在无法生成完整的回复。请稍后再试。");
                }
            }
        }, executorService);
    }

    /**
     * 判断是否应该生成图像
     */
    private boolean shouldGenerateImage(String textResponse, PersonaConfig persona) {
        // 根据人格类型和文本内容判断
        if ("chef".equals(persona.getId()) && 
            (textResponse.contains("食谱") || textResponse.contains("菜") || textResponse.contains("烹饪"))) {
            return true;
        }
        
        if ("doctor".equals(persona.getId()) && 
            (textResponse.contains("症状") || textResponse.contains("诊断") || textResponse.contains("治疗"))) {
            return true;
        }
        
        // 检查是否包含描述性内容
        return textResponse.contains("图片") || textResponse.contains("图像") || 
               textResponse.contains("展示") || textResponse.contains("看起来");
    }

    /**
     * 从文本中提取图像提示词
     */
    private String extractImagePromptFromText(String textResponse, PersonaConfig persona) {
        // 根据人格类型和文本内容生成图像提示词
        if ("chef".equals(persona.getId())) {
            if (textResponse.contains("食谱") || textResponse.contains("菜")) {
                return "delicious food dish, professional food photography, appetizing presentation";
            }
        }
        
        if ("doctor".equals(persona.getId())) {
            if (textResponse.contains("症状") || textResponse.contains("诊断")) {
                return "medical illustration, clean and professional, educational diagram";
            }
        }
        
        // 通用图像提示词生成
        return "illustration related to: " + textResponse.substring(0, Math.min(100, textResponse.length()));
    }

    /**
     * 保存输出记录到记忆系统
     */
    private void saveOutputToMemory(MultiModalOutputRequest request, MultiModalOutputResponse response) {
        try {
            if (request.getOptions() != null && request.getOptions().isSaveToMemory()) {
                StringBuilder memoryContent = new StringBuilder();
                memoryContent.append("用户输入: ").append(request.getInputText()).append("\n");
                
                if (StringUtils.hasText(response.getTextResponse())) {
                    memoryContent.append("文本回复: ").append(response.getTextResponse()).append("\n");
                }
                
                if (response.getImageResponse() != null) {
                    memoryContent.append("生成了图像: ").append(response.getImageResponse().getPrompt()).append("\n");
                }
                
                if (response.getVoiceResponse() != null) {
                    memoryContent.append("生成了语音回复\n");
                }
                
                memoryService.saveMemory(request.getUserId(), memoryContent.toString(), "multimodal_output");
            }
        } catch (Exception e) {
            log.warn("Failed to save output to memory for user: {}", request.getUserId(), e);
        }
    }

    /**
     * 获取用户的输出历史
     */
    public List<MultiModalOutputResponse> getUserOutputHistory(String userId, int limit) {
        // 这里应该从数据库或缓存中获取历史记录
        // 暂时返回空列表，实际实现需要持久化存储
        return new ArrayList<>();
    }

    /**
     * 清理资源
     */
    public void shutdown() {
        executorService.shutdown();
    }
}